home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / applic / ntp / acts.zoo / diftim.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-15  |  12.5 KB  |  475 lines

  1. void diftim(buf)
  2. char buf[280];
  3. {
  4. #include "nbstime.h"
  5. #include <stdio.h>
  6. #ifdef IBMPC
  7. #include <dos.h>
  8. #if defined(MSC)
  9. struct dosdate_t date;
  10. struct dostime_t time;
  11. #endif
  12. #endif
  13. char c;
  14. int j,yr,mo,day,hr,min,sec,dst;   /* holds parsed NBS time */
  15. int yribm,moibm,dayibm,hribm,minibm,secibm,hunibm; /* holds computer time */
  16. #ifdef IBMPC
  17. int yrat,moat,dayat,hrat,minat,secat;/* holds CMOS time for AT*/
  18. #endif
  19. int iterr = 0;
  20. float diff;                  /* holds time difference */
  21. float elapse;                  /* days since last comparison */
  22. float ddiff;                   /* difference of difference in sec */
  23. #ifdef IBMPC
  24. float adiff;                   /* same for IBMPC CMOS clock */
  25. #endif
  26. #ifdef IBMPC
  27. extern int utcdif;           /* local time - utc in hours */
  28. extern int dsflag;           /* daylight saving time? 1=yes, 0=no */
  29. extern int atflag;           /* AT-type machine? 1=yes, 0=no */
  30. static int lday[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; /*last day of month*/
  31. #endif
  32. static int tday[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334};
  33. int done = 0;         /* flag to show when comparison is complete */
  34. extern int wrtdif;    /*1=write dif to file, 0=don't 2=get rate too */
  35. extern int debug;     /* 1=debug on, 0=debug off */
  36. char *ptrslw,*ptrfas,*ptrrat;   /*output format strings*/
  37. #ifdef IBMPC
  38. int unpbcd();
  39. int dsdone=0;                /* flag to show conversion for daylight sav.*/
  40. #endif
  41. #ifdef SUN
  42. #include <sys/time.h>
  43. struct timeval tvv,*tp;
  44. struct tm gvv,*gv;
  45. #endif
  46. /*
  47.     the following structure holds the values computed the last
  48.     time the program was run as read to estimate the rate offset
  49.     of the clock.  the values are read by getlst() from the last 
  50.     line in file nbstime.dif if "A" mode was selected.  if "a" mode
  51.     was selected, this structure is not used.
  52. */
  53. extern struct tmprev
  54.     {
  55.     int yrprev;     /* time of previous comparison in first 6 values*/
  56.     int moprev;
  57.     int dyprev;
  58.     int hrprev;
  59.     int mnprev;
  60.     int scprev;
  61.     float dffprv;   /* value of difference followed by unts*/
  62.     char unprev;
  63. #ifdef IBMPC
  64.     float datprv;   /* difference and units for IBMPC CMOS clock*/
  65.     char uatprv;
  66. #endif
  67. } tmpp;
  68.         ptrslw="\n Computer clock slow by %.2f %s\n";
  69.         ptrfas="\n Computer clock fast by %.2f %s\n";
  70.     ptrrat="\n Approximate rate offset= %.3f sec/day.\n";
  71. /*
  72.         this subroutine receives a time string in character
  73.         array buf.  it is parsed and compared with the system
  74.         clock.  the origin of the parser is the - character between
  75.         the year and the month so that leading stuff will simply be
  76.         ignored.
  77.  
  78.     the IBMPC version performs the comparison using local time
  79.         this subroutine uses global variables dsflag to check for
  80.         daylight savings time and utcdif to convert from UTC to local
  81.         time
  82.  
  83.     the SUN version performs the comparison using UTC directly
  84.     since that is available from the system
  85.  
  86.  
  87.         begin by getting computer time now.
  88. */
  89. #ifdef IBMPC
  90. #if defined(MSC)
  91.     _dos_gettime(&time);
  92.     hribm=time.hour;
  93.     minibm=time.minute;
  94.     secibm=time.second;
  95.     hunibm=time.hsecond;
  96.     _dos_getdate(&date);
  97.     yribm=date.year;
  98.     moibm=date.month;
  99.     dayibm=date.day;
  100.     yribm -= 1900;
  101. #else
  102.         _AH=0x2c;
  103.         geninterrupt(0x21);
  104.         hribm=_CH;
  105.         minibm=_CL;
  106.         secibm=_DH;
  107.         hunibm=_DL;
  108.         _AH=0x2a;
  109.         geninterrupt(0x21);
  110.         yribm=_CX;
  111.         moibm=_DH;
  112.         dayibm=_DL;
  113.         yribm -= 1900;
  114. /*
  115.         if this is an at-type machine, read CMOS clock too
  116. */
  117.         if(atflag != 0)
  118.         {
  119.         _AH=2;
  120.         geninterrupt(0x1a);
  121.         hrat=_CH;
  122.         minat=_CL;
  123.         secat=_DH;
  124.         _AH=4;
  125.         geninterrupt(0x1a);
  126.         yrat=_CL;
  127.         moat=_DH;
  128.         dayat=_DL;
  129.         }
  130. #endif
  131. #endif
  132. #ifdef SUN
  133.     tp= &tvv;
  134.     gv= &gvv;
  135.     gettimeofday(tp,0);
  136.     gv=gmtime(tp);
  137.     yribm=gv->tm_year;
  138.     moibm=gv->tm_mon + 1;
  139.     dayibm=gv->tm_mday;
  140.     hribm=gv->tm_hour;
  141.     minibm=gv->tm_min;
  142.     secibm=gv->tm_sec;
  143.     hunibm=tp->tv_usec/10000;
  144. #endif
  145. /*
  146.         now parse line from NBS transmission
  147. */
  148.         for(j=0; (buf[j] != 0) && (buf[j] != '-') ; j++) ;
  149.         sscanf(&buf[j-2],"%2d-%2d-%2d %2d:%2d:%2d %d",&yr,&mo,&day,
  150.         &hr,&min,&sec,&dst);
  151. /*
  152.     for IBMPC version, convert to local time and
  153.     daylight savings time if necessary
  154.  
  155.      note that this conversion is not necessary for the
  156.     SUN which performs the comparison directly on UTC
  157. */
  158. #ifdef IBMPC
  159. /*
  160.         make standard-time portion of dst flag contiguous
  161. */
  162.         if(dst == 0) dst = 100;
  163. /*
  164.         convert from utc to local time. note that minute and second
  165.         are already correct.
  166.         daylight savings time flag must also be updated
  167.         if conversion to local time changes the day
  168.  
  169. */
  170.         if( (yr & 3) == 0 ) lday[2]=29;  /* 29 days for Feb in leap year */
  171.         hr += utcdif;                    /* convert hour to local time */
  172. /*
  173.         also do first part of conversion to daylight savings time
  174.         see parset and arcdif where same problem is dealt with
  175. */
  176.         if( (dsflag != 0) && (dst <= 50) && (dst > 1) )
  177.         {
  178.         hr++;
  179.         dsdone=1;
  180.         }
  181.         if(hr < 0)
  182.         {
  183.         hr += 24;
  184.         day--;
  185.         dst++;         /* update daylight savings flag for change of day
  186.  */
  187.         if(day < 1)
  188.            {
  189.            mo--;
  190.            if(mo < 1)
  191.               {
  192.               mo=12;
  193.               yr--;
  194.               }
  195.            day=lday[mo];
  196.            }
  197.         }
  198.         if(hr > 23)
  199.         {
  200.         hr -= 24;
  201.         day++;
  202.         dst--;        /* update daylight saving flag for change of day */
  203.         if(day > lday[mo])
  204.            {
  205.            day=1;
  206.            mo++;
  207.            if(mo > 12)
  208.               {
  209.               mo=1;
  210.               yr++;
  211.               }
  212.            }
  213.         }
  214. /*
  215.         now finish up daylight savings time if enabled
  216. */
  217.         if( (dsflag != 0) && (dsdone == 0) )
  218.         {
  219.            if( (dst == 51) && (hr >= 2) ) hr++;
  220.            if( (dst ==  1) && (hr <  2) ) hr++;
  221.         }
  222. #endif
  223. /*
  224.         ready to begin comparing the clocks
  225.         first print out both times
  226. */
  227.         printf("\n Computer time= %2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.%2.2d",
  228.               yribm,moibm,dayibm,hribm,minibm,secibm,hunibm);
  229.         printf("\n NBS time     = %2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.00",
  230.               yr,mo,day,hr,min,sec);
  231.         diff=365*(yribm - yr) + tday[moibm] - tday[mo] + dayibm - day;
  232.         if( ( (yribm & 3) == 0)  && (moibm > 2) ) diff++;
  233.         if( ( (yr    & 3) == 0)  && (mo    > 2) ) diff--;
  234. /*
  235.     compute time since last comparison if "A" mode was selected
  236.     time is computed as days and fractions
  237. */
  238.     if(wrtdif == 2)
  239.        {
  240.        elapse=365*(yr - tmpp.yrprev) +tday[mo] - tday[tmpp.moprev]
  241.         + day - tmpp.dyprev;
  242.        if( ( (yr & 3) == 0)  && (mo  >2) ) elapse++;
  243.        if( ( (tmpp.yrprev & 3) == 0) && (tmpp.moprev > 2) )elapse--;
  244.        elapse += ( (float) (hr - tmpp.hrprev) )/24. +
  245.                  ( (float) (min -tmpp.mnprev) )/1440. +
  246.                  ( (float) (sec -tmpp.scprev) )/86400.;
  247.        if(debug != 0) printf("\n time since last comparison=%f",elapse);
  248. /*
  249.     convert difference last time to seconds if necessary
  250. */
  251.     switch(tmpp.unprev)
  252.           {
  253.           case 'd':
  254.         ddiff = 86400.*tmpp.dffprv;
  255.         break;
  256.           case 'h':
  257.         ddiff = 3600.*tmpp.dffprv;
  258.         break;
  259.           case 'm':
  260.         ddiff = 60.*tmpp.dffprv;
  261.         break;
  262.           case 's':
  263.         ddiff=tmpp.dffprv;
  264.         break;
  265.           default:
  266.         printf("\n Units of difference= %c, not d,h,m,s.",
  267.             tmpp.unprev);
  268.         break;
  269.           }
  270.     if(debug != 0) printf("\n previous difference= %f sec.",ddiff);
  271.        }
  272.         if(diff > 1)
  273.         {
  274.         printf(ptrfas,diff,"days.");
  275.         done=1;
  276.         }
  277.         if(diff < -1)
  278.         {
  279.         printf(ptrslw,-diff,"days.");
  280.         done=1;
  281.         }
  282. /*
  283.     if difference has been printed as days and rate estimate
  284.     is selected, print value now
  285. */
  286.     if( (wrtdif == 2) && (done == 1) )
  287.        {
  288.        ddiff = (86400.*diff - ddiff)/elapse;
  289.        printf(ptrrat,ddiff);
  290.        }
  291.         if(done == 0)
  292.         {
  293.            diff= 24*diff + hribm - hr;
  294.            if(diff > 2)
  295.            {
  296.               printf(ptrfas,diff,"hours.");
  297.               done=1;
  298.            }
  299.            if(diff < -2)
  300.            {
  301.               printf(ptrslw,-diff,"hours.");
  302.               done=1;
  303.            }
  304.        if( (wrtdif == 2) && (done == 1) )
  305.         {
  306.         ddiff=(3600.*diff - ddiff)/elapse;
  307.         printf(ptrrat,ddiff);
  308.         }
  309.         }
  310.         if(done == 0)
  311.         {
  312.            diff=60*diff + minibm - min;
  313.            if(diff > 10)
  314.            {
  315.            printf(ptrfas,diff,"minutes.");
  316.            done=1;
  317.            }
  318.            if(diff < -10)
  319.            {
  320.            printf(ptrslw,-diff,"minutes.");
  321.            done=1;
  322.            }
  323.        if( (wrtdif == 2) && (done == 1) )
  324.         {
  325.         ddiff=(60.*diff - ddiff)/elapse;
  326.         printf(ptrrat,ddiff);
  327.         }
  328.         }
  329.         if(done == 0)
  330.         {
  331.            diff=60*diff + secibm - sec +  0.01*(float)hunibm;
  332.            if(diff > 0)
  333.               {
  334.               printf(ptrfas,diff,"seconds.");
  335. #ifdef IBMPC
  336.               iterr= 18.2*diff;
  337. #endif
  338.               }
  339.            if(diff < 0)
  340.               {
  341.               printf(ptrslw,-diff,"seconds.");
  342. #ifdef IBMPC
  343.               iterr= -18.2*diff;
  344. #endif
  345.               }
  346. #ifdef IBMPC
  347.            if(iterr == 0)
  348.               printf("Clocks agree to within 1 computer clock tick. \n");
  349.            else
  350.               printf("Difference is %d computer clock tick(s). \n",iterr);
  351. #endif
  352. #ifdef SUN
  353.        if(diff == 0)
  354.         printf("\n Clocks agree to within 10 msec. \n");
  355. #endif
  356.        if(wrtdif == 2)
  357.         {
  358.         ddiff= (diff - ddiff)/elapse;
  359.         printf(ptrrat,ddiff);
  360.         }
  361.         }
  362. #ifdef IBMPC
  363.         if(atflag == 0)return;
  364.         printf("\n\nCompare time of CMOS (Battery-run) Clock with NBS.\n");
  365. /*
  366.         begin comparison of CMOS time -- first convert from packed
  367.         BCD to normal binary, then compare as above.
  368. */
  369.         yrat=unpbcd(yrat);
  370.         moat=unpbcd(moat);
  371.         dayat=unpbcd(dayat);
  372.         hrat=unpbcd(hrat);
  373.         minat=unpbcd(minat);
  374.         secat=unpbcd(secat);
  375.         printf("\nCMOS time= %2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
  376.         yrat,moat,dayat,hrat,minat,secat);
  377.         printf("\nNBS  time= %2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
  378.         yr,mo,day,hr,min,sec);
  379.         diff=365*(yrat - yr) + tday[moat] - tday[mo] + dayat - day;
  380.         if( ( (yrat & 3) == 0) && (moat > 2) )  diff++;
  381.         if( ( (yr   & 3) == 0) && (mo   > 2) )  diff--;
  382. /*
  383.     if rate estimate was selected, convert previous difference
  384.     to seconds if necessary
  385. */
  386.     if(wrtdif == 2)
  387.        {
  388.        switch(tmpp.uatprv)
  389.         {
  390.         case 'd':
  391.            adiff=86400.*tmpp.datprv;
  392.            break;
  393.         case 'h':
  394.            adiff=3600.*tmpp.datprv;
  395.            break;
  396.         case 'm':
  397.            adiff=60.*tmpp.datprv;
  398.            break;
  399.         case 's':
  400.            adiff=tmpp.datprv;
  401.            break;
  402.         default:
  403.            printf("\n units of difference=%c, not d,h,m,s.",
  404.             tmpp.uatprv);
  405.         }
  406.        }
  407.         done=0;
  408.         if(diff > 1)
  409.         {
  410.            printf(ptrfas,diff,"days.");
  411.            done=1;
  412.         }
  413.         if(diff < -1)
  414.         {
  415.            printf(ptrslw,-diff,"days.");
  416.            done=1;
  417.         }
  418.     if ( (wrtdif == 2) && (done == 1) )
  419.        {
  420.        adiff=(86400.*diff - adiff)/elapse;
  421.        printf(ptrrat,adiff);
  422.        }
  423.         if(done == 0)
  424.         {
  425.         diff=24*diff + hrat - hr;
  426.         if(diff > 2)
  427.            {
  428.            printf(ptrfas,diff,"hours.");
  429.            done=1;
  430.            }
  431.         if(diff < -2)
  432.            {
  433.            printf(ptrslw,-diff,"hours.");
  434.            done=1;
  435.            }
  436.     if( (wrtdif == 2) && (done == 1) )
  437.        {
  438.        ddiff=(3600.*diff - adiff)/elapse;
  439.        printf(ptrrat,adiff);
  440.        }
  441.         }
  442.         if(done == 0)
  443.         {
  444.         diff=60*diff + minat - min;
  445.         if(diff > 10)
  446.            {
  447.            printf(ptrfas,diff,"minutes.");
  448.            done=1;
  449.            }
  450.         if(diff < -10)
  451.            {
  452.            printf(ptrslw,-diff,"minutes.");
  453.            done=1;
  454.            }
  455.     if( (wrtdif == 2) && (done == 1) )
  456.        {
  457.        adiff=(60.*diff - adiff)/elapse;
  458.        printf(ptrrat,adiff);
  459.        }
  460.         }
  461.         if(done == 0)
  462.         {
  463.         diff=60*diff +secat - sec;
  464.         if(diff > 0)  printf(ptrfas,diff,"seconds.");
  465.         if(diff < 0)  printf(ptrslw,-diff,"seconds.");
  466.         if(diff == 0) printf("\n Time agrees to within 1 second.\n");
  467.     if(wrtdif == 2)
  468.        {
  469.        adiff=(diff - adiff)/elapse;
  470.        printf(ptrrat,adiff);
  471.        }
  472.         }
  473. #endif
  474. }
  475.